import unittest
from myhomework.models import User,Group
from django.contrib.auth.models import Permission
from myhomework.account.daos import *
from myhomework.exceptions.exception import *
from django.contrib.auth.models import User as AuthUser


class  UserdaoTestCase(unittest.TestCase):
    def setUp(self):
        self.user1 = User(name='user1',student_id='08386051',email='1234@163.com',major='CAS')
        #self.user1.save()
        self.user2 = User(name='user2',student_id='08386052',email='56789@163.com',major='CAS')
        #self.user2.save()
        self.user3 = User(name='user3',student_id='08386053',email='78901@163.com',major='CAS')
        #self.user3.save()
    

    def test_add_user(self):
        '''test_add_user'''
        #test add a new user
        UserDao.add_user(self.user1)
        user1 = User.objects.get(student_id=self.user1.student_id)
        self.assertEquals(self.user1.student_id,user1.student_id)
        self.assertNotEquals(user1.auth_user,None)
        self.assertEquals(self.user1.student_id,user1.auth_user.username)
        #self.assertEquals(self.user1.student_id,user1.auth_user.password)
          
        #test add a new user student_id existed
        self.assertRaises(UserIDExisted, UserDao.add_user,user1)


    def test_edit_user(self):
        #edit an user not existed
        self.assertRaises(UserIDNotExisted, UserDao.edit_user,self.user2)
        
        #edit an user existed
        UserDao.add_user(self.user2)
        
        self.user2.name='newname'
        UserDao.edit_user(self.user2)
        user2=User.objects.get(student_id=self.user2.student_id)
        self.assertNotEquals(user2,None)
        self.assertEquals(user2.name,'newname')
        
    def test_get_user_by_student_id(self):
        UserDao.add_user(self.user3)
        user3=UserDao.get_user_by_student_id(self.user3.student_id)
        self.assertNotEquals(user3,None)
        self.assertEquals(user3.student_id,self.user3.student_id)







class  GroupdaoTestCase(unittest.TestCase):
    def setUp(self):
        self.user1 = User(name='user1',student_id='08386041',email='1234@163.com',major='CAS')
        UserDao.add_user(self.user1)
        self.user2 = User(name='user2',student_id='08386042',email='56789@163.com',major='CAS')
        UserDao.add_user(self.user2)
        self.user3 = User(name='user3',student_id='08386043',email='78901@163.com',major='CAS')
        UserDao.add_user(self.user3)
        
        self.user4 = User(name='user4',student_id='08386044',email='1234@163.com',major='CAS')
        UserDao.add_user(self.user4)
        self.user5 = User(name='user5',student_id='08386045',email='56789@163.com',major='CAS')
        UserDao.add_user(self.user5)
        self.user6 = User(name='user6',student_id='08386046',email='78901@163.com',major='CAS')
        UserDao.add_user(self.user6)
        
        self.user7 = User(name='user7',student_id='08386047',email='1234@163.com',major='CAS')
        UserDao.add_user(self.user7)
        self.user8 = User(name='user8',student_id='08386048',email='56789@163.com',major='CAS')
        UserDao.add_user(self.user8)
        self.user9 = User(name='user9',student_id='08386049',email='78901@163.com',major='CAS')
        UserDao.add_user(self.user9)
        
        
        self.group1 = Group(name='group1',administrator = self.user1)
        self.group1.save()
        self.user1.group=self.group1
        self.user1.save()
        PermissionDao.user_add_perms(self.user1.auth_user,['group1.admin','group1.member'])
        
        
        
        self.group2 = Group(name='group2',administrator = self.user2)
        self.group2.save()
        self.user2.group=self.group2
        self.user2.save()
        PermissionDao.user_add_perms(self.user2.auth_user,['group2.admin','group2.member'])
        
        
        self.group3 = Group(name='group3',administrator = self.user3)
        self.group3.save()
        self.user3.group=self.group3
        self.user3.save()
        PermissionDao.user_add_perms(self.user2.auth_user,['group3.admin','group3.member'])

        
    def tearDown(self):
        for user in User.objects.all():
            user.auth_user.delete()
            user.delete()
            
        for group in Group.objects.all():
            group.delete()
        for perm in Permission.objects.all():
            perm.delete()
            

        
    def test_add_group(self):
        #normal

        GroupDao.create_group('group4','08386044')
        group4 = Group.objects.get(name='group4')
        self.assertNotEquals(group4,None)
        self.assertEquals(group4.name,'group4')
        self.user4 = UserDao.get_user_by_student_id('08386044')
        self.assertEquals(group4,self.user4.group)
        self.assertEquals(group4.administrator,self.user4)
        self.assertEquals(self.user4 in group4.users.all(),True)
        self.assertEquals(PermissionDao.user_has_perm(self.user4.auth_user,'group4.admin'),True)
        self.assertEquals(PermissionDao.user_has_perm(self.user4.auth_user,'group4.member'),True)
        
        #group name existed

        self.assertRaises(GroupNameDuplication, GroupDao.create_group,'group4','08386045')
        self.assertEquals(self.user5.group,None)
        self.assertEquals(PermissionDao.user_has_perm(self.user5.auth_user,'group4.admin'),False)
        self.assertEquals(PermissionDao.user_has_perm(self.user5.auth_user,'group4.member'),False)
        
        #creator has been in another group
        self.assertRaises(UserJoinGroupDuplication, GroupDao.create_group,'group5','08386044')
        self.assertEquals(PermissionDao.user_has_perm(self.user4.auth_user,'group5.admin'),False)
        self.assertEquals(PermissionDao.user_has_perm(self.user4.auth_user,'group5.member'),False)
        
    def test_change_group_administrator_by_name(self):
        self.assertEquals(PermissionDao.user_has_perm(self.user1.auth_user,'group1.admin'),True)
        self.assertEquals(PermissionDao.user_has_perm(self.user1.auth_user,'group1.member'),True)
        #new administrator is not in the group
        self.assertRaises(UserNotInThisGroup, GroupDao.change_group_administrator_by_name,'group1','08386042')
        self.assertEquals(self.group1.administrator,self.user1)
        self.assertEquals(PermissionDao.user_has_perm(self.user1.auth_user,'group1.admin'),True)
        self.assertEquals(PermissionDao.user_has_perm(self.user1.auth_user,'group1.member'),True)
        
        self.assertEquals(PermissionDao.user_has_perm(self.user2.auth_user,'group1.admin'),False)
        self.assertEquals(PermissionDao.user_has_perm(self.user2.auth_user,'group1.member'),False)
        #normal
        self.user9.group = self.group1
        self.user9.save()
        PermissionDao.user_add_perm(self.user9.auth_user,'group1.member')
        
        self.assertEquals(self.user9.group, self.group1)
        GroupDao.change_group_administrator_by_name('group1','08386049')
        self.group1 = Group.objects.get(name='group1')
        self.assertEquals(self.group1.administrator,self.user9)
        self.assertEquals(self.user1.group,self.group1)
        self.assertEquals(PermissionDao.user_has_perm(self.user1.auth_user,'group1.admin'),False)
        self.assertEquals(PermissionDao.user_has_perm(self.user1.auth_user,'group1.member'),True)
        
        self.assertEquals(PermissionDao.user_has_perm(self.user9.auth_user,'group1.admin'),True)
        self.assertEquals(PermissionDao.user_has_perm(self.user9.auth_user,'group1.member'),True)

      
        #user is not in any group
        self.assertRaises(UserNotInAnyGroup, GroupDao.change_group_administrator_by_name,'group1','08386046')
        self.assertEquals(PermissionDao.user_has_perm(self.user9.auth_user,'group1.admin'),True)
        self.assertEquals(PermissionDao.user_has_perm(self.user9.auth_user,'group1.member'),True)
        self.assertEquals(PermissionDao.user_has_perm(self.user6.auth_user,'group1.admin'),False)
        self.assertEquals(PermissionDao.user_has_perm(self.user6.auth_user,'group1.member'),False)
    
    def test_delete_group_by_name(self):
        self.user4.group = self.group1
        self.user4.save()
        #group1:user1,user4
        GroupDao.delete_group_by_name('group1')
        self.user1 = UserDao.get_user_by_student_id('08386041')
        self.user4 = UserDao.get_user_by_student_id('08386044')
   
        self.assertEquals(self.user1.group,None)
        self.assertEquals(self.user4.group,None)
        self.assertEquals(PermissionDao.user_has_perm(self.user1.auth_user,'group1.member'),False)
        self.assertEquals(PermissionDao.user_has_perm(self.user1.auth_user,'group1.admin'),False)
    
        #a group not existed
        self.assertRaises(GroupNotExisted,GroupDao.delete_group_by_name,'groupxx')
        
    
    def test_edit_group_name_by_name(self):
        GroupDao.edit_group_name_by_name('group1','group10')
        self.group1 = GroupDao.get_group_by_name('group10')
        self.assertNotEquals(self.group1,None)
        
        #a existed group name
        self.assertRaises(GroupNameDuplication,GroupDao.edit_group_name_by_name,'group2','group3')
        
        #a group not existed
        self.assertRaises(GroupNotExisted,GroupDao.edit_group_name_by_name,'groupxx','group23')
        
    def test_join_group_by_name(self):
        GroupDao.join_group_by_name('group1','08386044')
        self.user4 = UserDao.get_user_by_student_id('08386044')
        self.assertEquals(self.user4.group,self.group1)
        self.assertEquals(PermissionDao.user_has_perm(self.user4.auth_user,'group1.member'),True)
        self.assertEquals(PermissionDao.user_has_perm(self.user4.auth_user,'group1.admin'),False)

        #user has already been a member of another group
        self.assertRaises(UserStillInAGroup,GroupDao.join_group_by_name,'group2','08386044')
        
        #group not existed
        self.assertRaises(GroupNotExisted,GroupDao.join_group_by_name,'group10','08386045')

        #user not existed
        self.assertRaises(UserIDNotExisted,GroupDao.join_group_by_name,'group1','08386055')
        
    def test_get_group_administrator_by_name(self):
        
        admin = GroupDao.get_group_administrator_by_name('group1')
        self.assertEquals(self.user1,admin)
        
        #group not existed
        self.assertRaises(GroupNotExisted,GroupDao.get_group_administrator_by_name,'group10')

    def test_quit_group_by_name(self):
        GroupDao.join_group_by_name('group1','08386044')
        GroupDao.join_group_by_name('group1','08386045')
        
        self.user4 = UserDao.get_user_by_student_id('08386044')
        self.user5 = UserDao.get_user_by_student_id('08386045')
        
        self.assertEquals(self.user4.group,self.group1)
        self.assertEquals(self.user5.group,self.group1)
        #group1:user1 user4 user5
        GroupDao.quit_group_by_name('group1','08386044')
        self.user4 = UserDao.get_user_by_student_id('08386044')
        #group1:user1 user5
        self.assertEquals(self.user4.group,None)
        self.assertEquals(PermissionDao.user_has_perms(self.user4.auth_user,['group1.admin','group1.member']),False)
        
        self.assertRaises(UserIsAministrator,GroupDao.quit_group_by_name,'group1','08386041')
        self.assertRaises(UserNotInThisGroup,GroupDao.quit_group_by_name,'group1','08386042')
        self.assertRaises(UserNotInAnyGroup,GroupDao.quit_group_by_name,'group1','08386046')
        
        GroupDao.quit_group_by_name('group1','08386045')
        self.user5 = UserDao.get_user_by_student_id('08386045')
        #group1:user1
        self.assertEquals(self.user5.group,None)
        self.assertEquals(PermissionDao.user_has_perms(self.user5.auth_user,['group1.admin','group1.member']),False)
        
        GroupDao.quit_group_by_name('group1','08386041')
        self.user1 = UserDao.get_user_by_student_id('08386041')
        
        self.assertEquals(self.user1.group,None)
        self.assertEquals(PermissionDao.user_has_perms(self.user1.auth_user,['group1.admin','group1.member']),False)
        #group was deleted when no member
        self.assertRaises(GroupNotExisted, GroupDao.get_group_by_name,'group1')
        
        self.assertRaises(GroupNotExisted, GroupDao.quit_group_by_name,'group1','08386041s')
        


class  PermissionDaoTestCase(unittest.TestCase):
    def setUp(self):
        for user in AuthUser.objects.all():
            user.delete()
        for perm in Permission.objects.all():
            perm.delete()
        self.user = AuthUser.objects.create_user(username='test_perm',email='xxx@153.com',password='123')
        self.user.save()
        
        self.user1 = AuthUser.objects.create_user(username='test_perm1',email='xxx@153.com',password='123')
        self.user1.save()

    def tearDown(self):
        for user in AuthUser.objects.all():
            user.delete()
            
        for perm in Permission.objects.all():
            perm.delete()

    def test_user_add_perm(self):
        PermissionDao.user_add_perm(self.user,'add_perm')
        perm = Permission.objects.filter(codename='add_perm').get()
        self.assertNotEquals(perm,None)
        self.assertEquals(perm in self.user.user_permissions.all(),True)
        
        PermissionDao.user_add_perm(self.user1,'add_perm')
        perm = Permission.objects.filter(codename='add_perm').get()
        self.assertNotEquals(perm,None)
        self.assertEquals(perm in self.user1.user_permissions.all(),True)
        
    def test_user_add_perms(self):
        PermissionDao.user_add_perms(self.user,['add_perms1','add_perms2'])

        perm1 = Permission.objects.filter(codename='add_perms1').get()
        perm2 = Permission.objects.filter(codename='add_perms2').get()
        self.assertNotEquals(perm1,None)
        self.assertNotEquals(perm2,None)
        self.assertEquals(perm1 in self.user.user_permissions.all(),True)
        self.assertEquals(perm2 in self.user.user_permissions.all(),True)
        
        
    def test_user_has_perm(self):
        p = Permission(name='1',content_type_id=1,codename='has_perm')
        p.save()
        self.user.is_active=True
        self.user.is_superuser=False
        self.user.user_permissions.add(p)
        self.assertEquals(PermissionDao.user_has_perm(self.user,'has_perm'),True)
        self.assertEquals(PermissionDao.user_has_perm(self.user,'has_perms3'),False)
        
        self.user.is_active=False
        
        self.assertEquals(PermissionDao.user_has_perm(self.user,'has_perm'),False)
        
        self.user.is_active = True
        self.user.is_superuser = True
        self.assertEquals(PermissionDao.user_has_perm(self.user,'has_perms3'),True)
        
    def test_user_has_perms(self):
        self.user.is_active=True
        self.user.is_superuser=False
        p1 = Permission(name='1',content_type_id=1,codename='has_perms1')
        p1.save()
        self.user.user_permissions.add(p1)
        self.assertEquals(PermissionDao.user_has_perms(self.user,['has_perms1','has_perms3']),True)
        self.assertEquals(PermissionDao.user_has_perms(self.user,['has_perms4','has_perms3']),False)
        
        
        
    def test_user_remove_perm(self):
        p = Permission(name='1',content_type_id=1,codename='remove_perm')
        p.save()
        self.user.user_permissions.add(p)
        
        p1 = Permission(name='1',content_type_id=1,codename='remove_perm1')
        p1.save()
        self.user.user_permissions.add(p1)
  
        PermissionDao.user_remove_perm(self.user,'remove_perm')
        self.assertEquals(p in self.user.user_permissions.all(),False)
        self.assertEquals(p1 in self.user.user_permissions.all(),True)
        
        PermissionDao.user_remove_perm(self.user,'remove_perm2')
        
        
    def test_user_remove_perms(self):
        p1 = Permission(name='1',content_type_id=1,codename='remove_perms1')
        p1.save()
        self.user.user_permissions.add(p1)
        p2 = Permission(name='2',content_type_id=1,codename='remove_perms2')
        p2.save()
        self.user.user_permissions.add(p2)
  
        PermissionDao.user_remove_perms(self.user,['remove_perms1','remove_perms2'])
        
        self.assertEquals(p1 in self.user.user_permissions.all(),False)
        self.assertEquals(p2 in self.user.user_permissions.all(),False)
        
    def test_user_get_all_perms(self):
        user = AuthUser.objects.create_user(username='test_perm2',email='xxx@153.com',password='123')
        user.save()
        
        p1 = Permission(name='1',content_type_id=1,codename='all_perms1')
        p1.save()
        user.user_permissions.add(p1)
        p2 = Permission(name='2',content_type_id=1,codename='all_perms2')
        p2.save()
        user.user_permissions.add(p2)
        
        self.assertEquals(set(PermissionDao.user_get_all_perms(user)),set(['all_perms1','all_perms2']))
        self.assertEquals(set(PermissionDao.user_get_all_perms(None)),set([]))

